package org.oneblog.service;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Transparency;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;

import javax.imageio.ImageIO;
import javax.media.jai.PlanarImage;

import org.apache.commons.io.IOUtils;
import org.oneblog.bean.ImageConfiger;
import org.oneblog.bean.ImagePath;
import org.oneblog.data.util.StaticValue;
import org.oneblog.util.ImageUtils;

import com.alibaba.simpleimage.ImageFormat;
import com.alibaba.simpleimage.ImageWrapper;
import com.alibaba.simpleimage.SimpleImageException;
import com.alibaba.simpleimage.render.CropParameter;
import com.alibaba.simpleimage.render.ScaleParameter;
import com.alibaba.simpleimage.render.ScaleParameter.Algorithm;
import com.alibaba.simpleimage.render.WatermarkParameter;
import com.alibaba.simpleimage.render.WriteParameter;
import com.alibaba.simpleimage.util.ImageCropHelper;
import com.alibaba.simpleimage.util.ImageDrawHelper;
import com.alibaba.simpleimage.util.ImageReadHelper;
import com.alibaba.simpleimage.util.ImageScaleHelper;
import com.alibaba.simpleimage.util.ImageWriteHelper;

public class AbstractImageService {
    
    private String currentYearMonth() {
        return StaticValue.DateFormat.SIMPLE_YEAR_MONTH.format(new Date());
    }
    private String currentDayHour() {
        return StaticValue.DateFormat.SIMPLE_DAY_HH.format(new Date());
    }
    
    private void createFolderIfNotExist(String fullPath) {
        File folder = new File(fullPath);
        
        if(!folder.exists()) {
            folder.mkdirs();
        }
    }

    //图片存储在指定目录；BASE_FOLDER
    //按照时间格式进行目录拆分，方便文件管理和查找;yyyyMM/ddHH/nanoTime.jpg
    //确认目录是否存在
    protected ImagePath ensureFolderPath(String base) {
        ImagePath path = new ImagePath();
        System.out.println("base " + base);
        
        String relativePath = currentYearMonth() + "/" + currentDayHour() + "/";
        
        String fullPath = base + relativePath;
        
        path.setFullPath(fullPath);
        path.setRelativePath(relativePath);
        
        createFolderIfNotExist(fullPath);
        
        return path;
    }
    

    protected static ImageFormat outputFormat = ImageFormat.JPEG;
    //等比例缩放
    public final static void scaleNormal(String src, String target, int width, int height) {
        File out = new File(target); // 目的图片
        FileOutputStream outStream = null;
        File in = new File(src); // 原图片
        FileInputStream inStream = null;
        try {
            inStream = new FileInputStream(in);
            ImageWrapper imageWrapper = ImageReadHelper.read(inStream);
 
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            // 1.缩放
            ScaleParameter scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS); // 缩放参数
            CropParameter cropParam = new CropParameter(0, 0, width, height);// 裁切参数
            float srcRatio = (float) w / h;
            float dstRatio = (float) width / height;// 源宽高比和目标宽高比
            if (w < width && h < height) {// 如果图片宽和高都小于目标图片则不做缩放处理
                scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS);
                cropParam = new CropParameter(0, 0, w, h);
            } else if (srcRatio >= dstRatio) {
                int newWidth = ImageUtils.getWidth(w, h, height);
                scaleParam = new ScaleParameter(newWidth + 1, height, Algorithm.LANCZOS);
                cropParam = new CropParameter((newWidth - width) / 2, 0, width, height);
 
            } else if (srcRatio < dstRatio) {
                int newHeight = ImageUtils.getHeight(w, h, width);
                scaleParam = new ScaleParameter(width, newHeight + 1, Algorithm.LANCZOS);
                cropParam = new CropParameter(0, (newHeight - height) / 2, width, height);
            }
            PlanarImage planrImage = ImageScaleHelper.scale(imageWrapper.getAsPlanarImage(), scaleParam);
            // 2.裁切
            imageWrapper = new ImageWrapper(planrImage);
            planrImage = ImageCropHelper.crop(planrImage, cropParam);
            imageWrapper = new ImageWrapper(planrImage);
            // 4.输出
            outStream = new FileOutputStream(out);
            String prefix = out.getName().substring(out.getName().lastIndexOf(".") + 1);
            ImageWriteHelper.write(imageWrapper, outStream, ImageFormat.getImageFormat(prefix), new WriteParameter());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(inStream); // 图片文件输入输出流必须记得关闭
            IOUtils.closeQuietly(outStream);
 
        }
    }
    /**
     * 缩放到指定宽度 高度自适应
     * @param src
     * @param target
     * @param width
     */
    public final static void scaleWithWidth(InputStream srcInputStream, String target, ImageConfiger configer, InputStream warterStream) {
        File out = new File(target); // 目的图片
        FileOutputStream outStream = null;
        try {
            Integer width = configer.getTargetWidth();
            ImageWrapper imageWrapper = ImageReadHelper.read(srcInputStream);
 
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            PlanarImage planrImage = null;
            
            //剪裁
            if(configer.hasCut()) {
                float x = configer.getX().floatValue();
                float y = configer.getY().floatValue();
                int cutWidth = configer.getWidth().intValue();
                int cutHeight = configer.getHeight().intValue();
                
                if(x < 0) {//负数，从0开始，宽度对应缩小
                    cutWidth = (int) (cutWidth + x);
                    x = 0;
                }
                if(y < 0) {//负数，从0开始，高度对应缩小
                    cutHeight = (int) (cutHeight + y);
                    y = 0;
                }
                
                //不能超出
                cutWidth = (int) Math.min(w - x, cutWidth);
                cutHeight = (int) Math.min(h - y, cutHeight);
                        
                CropParameter cropParam = new CropParameter(x, y, cutWidth, cutHeight);// 裁切参数
                planrImage = ImageCropHelper.crop(imageWrapper.getAsPlanarImage(), cropParam);
                imageWrapper = new ImageWrapper(planrImage);
            }

            // 1.缩放
            ScaleParameter scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS); // 缩放参数
            if (w < width) {// 如果图片宽和高都小于目标图片则不做缩放处理
                scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS);
            } else {
                int newHeight = ImageUtils.getHeight(w, h, width);
                scaleParam = new ScaleParameter(width, newHeight + 1, Algorithm.LANCZOS);
            }
            
            planrImage = ImageScaleHelper.scale(imageWrapper.getAsPlanarImage(), scaleParam);
            imageWrapper = new ImageWrapper(planrImage);

            if(warterStream != null) {
                // 3.打水印
                BufferedImage waterImage = ImageIO.read(warterStream);
                ImageWrapper waterWrapper = new ImageWrapper(waterImage);
                WatermarkParameter param = new WatermarkParameter(waterWrapper, 1, width - waterWrapper.getWidth(), scaleParam.getMaxHeight() - waterWrapper.getHeight());
                imageWrapper = new ImageWrapper(planrImage);
                BufferedImage bufferedImage = ImageDrawHelper.drawWatermark(imageWrapper.getAsBufferedImage(), param);
                imageWrapper = new ImageWrapper(bufferedImage);
            }
            
            // 4.输出
            outStream = new FileOutputStream(out);
            String prefix = out.getName().substring(out.getName().lastIndexOf(".") + 1);

            ImageWriteHelper.write(imageWrapper, outStream, ImageFormat.getImageFormat(prefix), new WriteParameter());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(srcInputStream); // 图片文件输入输出流必须记得关闭
            IOUtils.closeQuietly(outStream);
        }
 
    }
    /**
     * 缩放到指定高度，宽度自适应
     * @param src
     * @param target
     * @param height
     */
    public final static void scaleWithHeight(String src, String target, Integer height) {
        File out = new File(target); // 目的图片
        FileOutputStream outStream = null;
        File in = new File(src); // 原图片
        FileInputStream inStream = null;
        try {
            inStream = new FileInputStream(in);
            ImageWrapper imageWrapper = ImageReadHelper.read(inStream);
 
            int w = imageWrapper.getWidth();
            int h = imageWrapper.getHeight();
            // 1.缩放
            ScaleParameter scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS); // 缩放参数
            if (w < height) {// 如果图片宽和高都小于目标图片则不做缩放处理
                scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS);
 
            } else {
                int newWidth = ImageUtils.getWidth(w, h, height);
                scaleParam = new ScaleParameter(newWidth + 1, height, Algorithm.LANCZOS);
 
            }
            PlanarImage planrImage = ImageScaleHelper.scale(imageWrapper.getAsPlanarImage(), scaleParam);
            imageWrapper = new ImageWrapper(planrImage);
            // 4.输出
            outStream = new FileOutputStream(out);
            String prefix = out.getName().substring(out.getName().lastIndexOf(".") + 1);
            ImageWriteHelper.write(imageWrapper, outStream, ImageFormat.getImageFormat(prefix), new WriteParameter());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SimpleImageException e) {
        } finally {
            IOUtils.closeQuietly(inStream); // 图片文件输入输出流必须记得关闭
            IOUtils.closeQuietly(outStream);
 
        }
 
    }
    //////////
    public static Integer getHeight(Integer w, Integer h, Integer width) {
 
        return h * width / w;
    }

    public static Integer getWidth(Integer w, Integer h, Integer height) {
        return w * height / h;
    }
    public static InputStream circleImg(BufferedImage bi1) throws IOException {

        BufferedImage image = new BufferedImage(bi1.getWidth(), bi1.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
  
        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1
                .getHeight());
         
        Graphics2D g2 = image.createGraphics();
        image = g2.getDeviceConfiguration().createCompatibleImage(bi1.getWidth(), bi1.getHeight(), Transparency.TRANSLUCENT);
        g2 = image.createGraphics();
        g2.setComposite(AlphaComposite.Clear);
        g2.fill(new Rectangle(image.getWidth(), image.getHeight()));
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f));
        g2.setClip(shape);
        // 使用 setRenderingHint 设置抗锯齿
        g2.drawImage(bi1, 0, 0, null);
        g2.dispose();
        ByteArrayOutputStream os = new ByteArrayOutputStream();  
        ImageIO.write(image, "png", os);  
        InputStream is = new ByteArrayInputStream(os.toByteArray());  
        return is;
    }

    public static ImageWrapper placeImage(ImageWrapper dist, String imageUrl, int x, int y, int width, int height, boolean isCircle) throws Exception {

        BufferedImage urlImage = ImageIO.read(new URL(imageUrl));
        
        return placeImage(dist, urlImage, x, y, width, height, isCircle);
    }
    public static ImageWrapper placeImage(ImageWrapper dist, BufferedImage src, int x, int y, int width, int height, boolean isCircle) throws Exception {
        ImageWrapper waterWrapper = null;
        InputStream is = null;
        if(isCircle) {
            is = circleImg(src);
            waterWrapper = ImageReadHelper.read(is);
        } else {
            waterWrapper = new ImageWrapper(src);
        }
        
        //缩放src图片
        int w = waterWrapper.getWidth();
        int h = waterWrapper.getHeight();
        // 1.缩放
        ScaleParameter scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS); // 缩放参数
        float srcRatio = (float) w / h;
        float dstRatio = (float) width / height;// 源宽高比和目标宽高比
        if (w < width && h < height) {// 如果图片宽和高都小于目标图片则不做缩放处理
            scaleParam = new ScaleParameter(w, h, Algorithm.LANCZOS);
        } else if (srcRatio >= dstRatio) {
            int newHeight = getHeight(w, h, width);
            scaleParam = new ScaleParameter(width + 1, newHeight + 1, Algorithm.LANCZOS);
        } else if (srcRatio < dstRatio) {
            int newWidth = getWidth(w, h, height);
            scaleParam = new ScaleParameter(newWidth + 1, height, Algorithm.LANCZOS);
        }
        PlanarImage planrImage = ImageScaleHelper.scale(waterWrapper.getAsPlanarImage(), scaleParam);
        waterWrapper = new ImageWrapper(planrImage);
        
        WatermarkParameter param = new WatermarkParameter(waterWrapper, 1, x, y);
        
        BufferedImage bufferedImage = ImageDrawHelper.drawWatermark(dist.getAsBufferedImage(), param);
        
        dist = new ImageWrapper(bufferedImage);
        
        if(is != null) {
            is.close();
        }
        
        return dist;
    }
    
    static void d() throws IOException {
        BufferedImage bi1 = ImageIO.read(new File(folder + "gh_b5f9f166404d_258.jpg"));
        BufferedImage image = new BufferedImage(bi1.getWidth(), bi1.getHeight(),
                BufferedImage.TYPE_INT_ARGB);
  
        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1
                .getHeight());
         
        Graphics2D g2 = image.createGraphics();
        image = g2.getDeviceConfiguration().createCompatibleImage(bi1.getWidth(), bi1.getHeight(), Transparency.TRANSLUCENT);
        g2 = image.createGraphics();
        g2.setComposite(AlphaComposite.Clear);
        g2.fill(new Rectangle(image.getWidth(), image.getHeight()));
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f));
        g2.setClip(shape);
        // 使用 setRenderingHint 设置抗锯齿
        g2.drawImage(bi1, 0, 0, null);
        g2.dispose();
         
        try {
            ImageIO.write(image, "PNG", new File(folder + "gh_b5f9f166404d_258000000000.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    static ImageWrapper locateTxt(BufferedImage src, String txt) throws IOException, SimpleImageException {
        Graphics2D g2 = src.createGraphics();

        g2.setColor(Color.red);
        g2.setFont(new Font("宋体", Font.BOLD, 25));
        g2.drawString(txt, 100, 200);
        
        g2.dispose();
        ByteArrayOutputStream os = new ByteArrayOutputStream();  
        ImageIO.write(src, "png", os);  
        InputStream is = new ByteArrayInputStream(os.toByteArray());  
        ImageWrapper iw = ImageReadHelper.read(is);
        if(is != null) {
            is.close();
        }
        return iw;
    }
    
    static final String folder = "/Users/wjyuian/mnt/img1/";
    public static void main(String[] args) throws SimpleImageException, Exception {
        float radio = 120F/86;
        String bg = folder + "share_card_bg.png";
        String priceBg = folder + "price_circle.png";
        String t = folder + "gh_b5f9f166404d_258.jpg";
        FileOutputStream outStream = new FileOutputStream(new File(folder + "testout.png"));
        
        //生成底图
        ImageWrapper imageWrapper = ImageReadHelper.read(new FileInputStream(new File(bg)));
        
        BufferedImage src = ImageIO.read(new FileInputStream(new File(t)));

//        BufferedImage urlImage = ImageIO.read(new URL("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2546351486,3508634881&fm=26&gp=0.jpg"));
//        imageWrapper = placeImage(imageWrapper, urlImage, 300, 800, 70, 70);
        
        
        //覆盖商品主图
        
        //覆盖头像
        imageWrapper = placeImage(imageWrapper, src, 120, 770, 74, 74, true);
        
        //覆盖价格图；价格外圈图
        BufferedImage priceCircle = ImageIO.read(new FileInputStream(new File(priceBg)));
        imageWrapper = placeImage(imageWrapper, priceCircle, (int)(341 * radio), (int)(431 * radio), 180, 180, true);
        
        
        //覆盖二维码
        imageWrapper = placeImage(imageWrapper, src, 468, 850, 156, 156, true);
        
        //覆盖商品标题
        
        //覆盖商户名字和logo
        String shopName = "智美优选";
        String shopLogo = "https://contenttest02.joowing.com/content_node/contents/content_agent:6b6a0c40-204f-0137-451b-0242ac1e3b59/access";
        BufferedImage urlImage = ImageIO.read(new URL(shopLogo));
        imageWrapper = placeImage(imageWrapper, urlImage, (int)(280 * radio), (int)(781 * radio), 140, 55, false);
//        d();
        imageWrapper = locateTxt(imageWrapper.getAsBufferedImage(), shopName);

        
        ImageWriteHelper.write(imageWrapper, outStream, ImageFormat.getImageFormat("png"), new WriteParameter());
        
    }
}
